#include "init.h"
#include "comm/boot_info.h"
#include "cpu/cpu.h"
#include "cpu/irq.h"
#include "dev/time.h"
#include "tools/log.h"
#include "os.cfg.h"
#include "tools/kilb.h"
#include "core/task.h"
#include "tools/list.h"
#include "ipc/sem.h"
#include "core/memory.h"
#include "dev/console.h"
#include "dev/kbd.h"
#include "fs/fs.h"

// #define static sem_t sem;

// test data segment and code segment
// int global_var=0x1234;
// int global_var_zreo;
// static int  static_global_var=0x2345;
// static int static_global_var_zero;

void kernel_init(boot_info_t *boot_info)
{
    // test data segment and code segment
    // int local_var;
    // static int static_global_var =0x33;
    // static int static_global_var_zero;

    cpu_init();
    irq_init();
    log_init();
    // console_init();
    time_init();
    memory_init(boot_info);
    fs_init();
    // kbd_init();
}

// // define init_task(用户创建shell等任务),init_main(first_task)操作系统哦
// static task_t init_task_t;
// static task_t first_task_t;
// // in consideration of tss init_task isn't stack esp, must crest a stack for it, here create a array for it
// static uint32_t init_task_stack[1024];

// tow test function
// void init_task(void)
// {
//     int count = 0;
//     for (;;)
//     {
//         sem_wait(&sem);
//         log_printf("init_task   count %d", count);
//         count++;
//         // task_switch_from_to(&init_task_t, task_first_task());
//         // sys_sched_yield();
//         // sys_sleep(500);
//     }
// }
void move_to_first_task(void)
{
    task_t *curr = task_current();
    ASSERT(curr != 0);
    tss_t *tss = &(curr->tss);
    // 修改tss的值，还记得eip吗？ 用内联汇编
    // eip 就是first_task_entry 的入口地址
    __asm__ __volatile__(
        "push %[ss]\n\t"
        "push %[esp]\n\t"
        "push %[eflags]\n\t"
        "push %[cs]\n\t"
        "push %[eip]\n\t"
        "iret" 
        ::[ss] "r"(tss->ss),
        [esp] "r"(tss->esp),
        [eflags] "r"(tss->eflags), 
        [cs] "r"(tss->cs),
        [eip] "r"(tss->eip));
}

    void
    init_main(void)
{
    // test list
    // list_test();
    log_printf("===========================================");
    log_printf("kernel is run......\n");
    log_printf("OS_VERSION:%s,%s\n", OS_VERSION, "kernel run now!");
    log_printf("%d %d %x %c\n", 123, -123, 15, 'l');
    log_printf("===========================================");
    // test divide zero exception
    // int a=3;
    // int b=a/0;

    // test assert
    // ASSERT(3<2);

    // init init_task and first_task
    // i think first_task_t is symbol the init_main process, it is OS process
    // task_init(&first_task_t, 0, 0);
    // (uint32_t)&init_task_stack[1024] 堆栈从高地址到低地址，故要初始化数组最后一个元素为栈顶
    task_manager_init();
    task_first_init();
    move_to_first_task();

    // task_init(&init_task_t, (uint32_t)init_task, (uint32_t)&init_task_stack[1023], "init task");

    // write_tr(first_task_t.tss_sel);
    // test sem
    // sem_init(&sem, 0);

    // irq_enable_gloabl();
    // int count = 0;
    // for (;;)
    // {
    //     log_printf("init main:    %d", count++);
    //     // task_switch_from_to(task_first_task(), &init_task_t);
    //     // sys_sched_yield();
    //     sem_notify(&sem);
    //     sys_sleep(1000);
    // }
    // init_task();

    // for (;;)
    // {
    // }
}
